﻿using System;
using System.Net.Sockets;

namespace AsyncEvtEcho
{
    /// <summary>
    /// use a Finite State Machine (FSM) to receive the data
    /// </summary>
    sealed class HeadBodyRecver
    {
        // *************************************************************** //
        #region [ member fields ]

        private readonly HeadState m_headState;
        private readonly BodyState m_bodyState;
        private RecvStateBase m_currentState;

        #endregion

        // *************************************************************** //
        #region [ constructor ]

        public HeadBodyRecver()
        {
            m_headState = new HeadState(this);
            m_bodyState = new BodyState(this);
            m_currentState = m_headState;
        }

        #endregion

        // *************************************************************** //
        #region [ public APIs ]

        public void OnHeadReceived(Header header)
        {
            m_bodyState.WholeLength = header.Size;
            m_currentState = m_bodyState;
        }

        public void OnBodyReceived()
        {
            m_currentState = m_headState;
        }

        public bool Receive(byte[] buffer, int offset, int count)
        {
            return m_currentState.Receive(buffer, offset, count);
        }

        public Tuple<byte[], int, int> NextRead
        {
            get { return m_currentState.NextRead; }
        }

        public Tuple<Header, byte[]> LastPacket
        {
            get { return Tuple.Create(m_headState.Header, m_bodyState.Body); }
        }

        #endregion
    }
}
